#pragma once

#include "Device.hpp"

#include <string>
#include <vector>

namespace hamster
{
    struct PipelineConfigInfo {
        VkViewport viewport;
        VkRect2D scissor;
        // VkPipelineViewportStateCreateInfo viewportInfo;
        VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo;
        VkPipelineRasterizationStateCreateInfo rasterizationInfo;
        VkPipelineMultisampleStateCreateInfo multisampleInfo;
        VkPipelineColorBlendAttachmentState colorBlendAttachment;
        VkPipelineColorBlendStateCreateInfo colorBlendInfo;
        VkPipelineDepthStencilStateCreateInfo depthStencilInfo;
        VkPipelineLayout pipelineLayout = nullptr;
        VkRenderPass renderPass = nullptr;
        uint32_t subpass = 0;
      };

    class Hamster_Pipeline
    {
        public:
            Hamster_Pipeline(
                Device& other_device,
                const std::string& vertFilePath, 
                const std::string& fragFilePath,
                const PipelineConfigInfo& configInfo);

            ~Hamster_Pipeline();

            Hamster_Pipeline(const Hamster_Pipeline&) = delete;
            void operator=(const Hamster_Pipeline&) = delete;

            static PipelineConfigInfo defaultPipelineConfigInfo(
                uint32_t width, 
                uint32_t height);

            void bind(VkCommandBuffer commandBuffer);

        private:
            static std::vector<char> readFile(const std::string& filename);
            
            void createGraphicsPipeline(
                const std::string& vertFilePath, 
                const std::string& fragFilePath,
                const PipelineConfigInfo& configInfo
            );

            void createShaderModule(
                const std::vector<char>& code,
                VkShaderModule* shaderModule
            );

            Device& device;
            VkPipeline graphicsPipeline;
            VkShaderModule vertShaderModule;
            VkShaderModule fragShaderModule;
    };
}